#include <cstdio>
#include <iostream>
#include <sstream>
#include <unistd.h>

class Object {
public:
    Object() {}
    virtual ~Object() {}
    virtual void A() {}
    virtual void B() {}
    virtual void C() {}
    virtual void D() {}
};

class Object2 : public Object {
public:
    Object2() {}
    virtual ~Object2() {}
    virtual void A() override {}
    virtual void C() override {}
};

int main()
{
    {
        Object o;
        uint64_t *vptr = reinterpret_cast<uint64_t *>(&o);
        uint64_t *vtbl = (uint64_t *)(*vptr);
        std::cout << "Object virtual function:" << vtbl << std::endl;
        std::cout << std::hex << std::showbase << "  ?: " << vtbl[0] << std::endl;
        std::cout << std::hex << std::showbase << "  ~: " << vtbl[1] << std::endl;
        std::cout << std::hex << std::showbase << "  A: " << vtbl[2] << std::endl;
        std::cout << std::hex << std::showbase << "  B: " << vtbl[3] << std::endl;
        std::cout << std::hex << std::showbase << "  C: " << vtbl[4] << std::endl;
        std::cout << std::hex << std::showbase << "  D: " << vtbl[5] << std::endl;
        std::cout << std::endl;
    }

    {
        Object2 o2;
        uint64_t *vptr = reinterpret_cast<uint64_t *>(&o2);
        uint64_t *vtbl = (uint64_t *)(*vptr);
        std::cout << "Object2 virtual function:" << vtbl << std::endl;
        std::cout << std::hex << std::showbase << "  ?: " << vtbl[0] << std::endl;
        std::cout << std::hex << std::showbase << "  ~: " << vtbl[1] << std::endl;
        std::cout << std::hex << std::showbase << "  A: " << vtbl[2] << std::endl;
        std::cout << std::hex << std::showbase << "  B: " << vtbl[3] << std::endl;
        std::cout << std::hex << std::showbase << "  C: " << vtbl[4] << std::endl;
        std::cout << std::hex << std::showbase << "  D: " << vtbl[5] << std::endl;
        std::cout << std::endl;
    }

    std::stringstream ss;
    ss << "cat /proc/" << getpid() << "/maps";
    system(ss.str().c_str());
    return 0;
}
